#!/usr/bin/env python3
"""
批量修复所有语言的暗色模式语法高亮

位置: scripts/batch_fix_dark_mode.py
用法: python3 scripts/batch_fix_dark_mode.py
"""

import os
import re
import sys

# 获取项目根目录
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.dirname(SCRIPT_DIR)

# QScintilla 源码目录
QSCINT_DIR = os.path.join(PROJECT_ROOT, "src/qscint/src")

# 暗色主题检测代码模板
THEME_DETECTION = """    // 检测是否为暗色主题
    const int lightThemes[] = {0, 3, 7, 9, 17};
    bool isLightTheme = false;
    
    for (int id : lightThemes)
    {
        if (m_themesId == id)
        {
            isLightTheme = true;
            break;
        }
    }
"""

# 常见暗色颜色值（十六进制）
DARK_COLORS = {
    # 黑色 → 浅灰色
    "0x00,0x00,0x00": "0xd4,0xd4,0xd4",
    "0x0,0x0,0x0": "0xd4,0xd4,0xd4",
    
    # 深绿色 → 亮绿色
    "0x00,0x7f,0x00": "0x6a,0x99,0x55",
    "0x0,0x7f,0x0": "0x6a,0x99,0x55",
    "0x00,0x80,0x00": "0x6a,0xc9,0x6a",
    "0x0,0x80,0x0": "0x6a,0xc9,0x6a",
    "0x00,0x88,0x00": "0x6a,0xc9,0x6a",
    "0x0,0x88,0x00": "0x6a,0xc9,0x6a",
    
    # 深蓝色 → 亮蓝色
    "0x00,0x00,0xff": "0x56,0x9c,0xd6",
    "0x0,0x0,0xff": "0x56,0x9c,0xd6",
    "0x00,0x00,0x88": "0x70,0xa0,0xff",
    "0x0,0x0,0x88": "0x70,0xa0,0xff",
    "0x00,0x00,0x7f": "0x70,0xa0,0xff",
    "0x0,0x0,0x7f": "0x70,0xa0,0xff",
    
    # 深紫色 → 亮紫色
    "0x7f,0x00,0x7f": "0xce,0x91,0x78",  # 改为橙色（字符串）
    "0x80,0x00,0xff": "0xdc,0xdc,0xaa",  # 改为黄色（函数）
    "0x88,0x00,0x88": "0xd8,0x88,0xd8",
    
    # 深青色 → 亮青色
    "0x00,0x7f,0x7f": "0xb5,0xce,0xa8",  # 改为浅绿（数字）
    "0x0,0x7f,0x7f": "0xb5,0xce,0xa8",
    "0x00,0x88,0x88": "0x5d,0xce,0xce",
    "0x0,0x88,0x88": "0x5d,0xce,0xce",
    
    # 深红色 → 橙红色
    "0x7f,0x00,0x00": "0xd8,0x96,0x78",
    "0x80,0x00,0x00": "0xd8,0x96,0x78",
    "0x88,0x00,0x00": "0xd8,0x96,0x78",
    
    # 深灰色 → 浅灰色
    "0x80,0x80,0x80": "0xd4,0xd4,0xd4",
    "0x7f,0x7f,0x7f": "0xb0,0xb0,0xb0",
}

def has_dark_theme_support(content):
    """检查文件是否已经有暗色主题支持"""
    return "isLightTheme" in content and "const int lightThemes[]" in content

def add_dark_theme_to_defaultColor(filepath):
    """为 defaultColor() 函数添加暗色主题支持"""
    with open(filepath, 'r', encoding='utf-8') as f:
        content = f.read()
    
    # 如果已经有支持，跳过
    if has_dark_theme_support(content):
        print(f"  ✓ 已支持暗色主题: {os.path.basename(filepath)}")
        return False
    
    # 查找 defaultColor 函数
    pattern = r'(QColor\s+\w+::defaultColor\s*\([^)]+\)\s*const\s*\{)'
    match = re.search(pattern, content)
    
    if not match:
        print(f"  ✗ 未找到 defaultColor: {os.path.basename(filepath)}")
        return False
    
    # 在函数开始处插入主题检测代码
    insert_pos = match.end()
    new_content = (
        content[:insert_pos] + 
        "\n" + THEME_DETECTION + "\n" +
        content[insert_pos:]
    )
    
    # 替换颜色值为条件表达式
    for old_color, new_color in DARK_COLORS.items():
        # 匹配 adjustColorForTheme(QColor(...)) 或 QColor(...)
        old_pattern = f"adjustColorForTheme\\(QColor\\({old_color}\\)\\)"
        new_pattern = f"(isLightTheme ? QColor({old_color}) : QColor({new_color}))"
        new_content = new_content.replace(old_pattern, new_pattern)
        
        # 也处理直接返回的情况
        old_pattern2 = f"return QColor\\({old_color}\\)"
        new_pattern2 = f"return (isLightTheme ? QColor({old_color}) : QColor({new_color}))"
        new_content = new_content.replace(old_pattern2, new_pattern2)
    
    with open(filepath, 'w', encoding='utf-8') as f:
        f.write(new_content)
    
    print(f"  ✓ 已修复: {os.path.basename(filepath)}")
    return True

def add_dark_theme_to_defaultPaper(filepath):
    """为 defaultPaper() 函数添加暗色主题支持（去掉背景色）"""
    with open(filepath, 'r', encoding='utf-8') as f:
        content = f.read()
    
    # 查找 defaultPaper 函数
    pattern = r'(QColor\s+\w+::defaultPaper\s*\([^)]+\)\s*const\s*\{)'
    match = re.search(pattern, content)
    
    if not match:
        return False  # 没有 defaultPaper 函数，跳过
    
    # 检查是否已经有暗色主题支持
    function_start = match.start()
    function_content = content[function_start:function_start+2000]  # 查看函数前2000字符
    
    if "暗色模式下不设置背景色" in function_content:
        return False  # 已经修复过
    
    # 在函数开始处插入
    insert_pos = match.end()
    insert_code = """
    // 检测是否为暗色主题
    const int lightThemes[] = {0, 3, 7, 9, 17};
    bool isLightTheme = false;
    
    for (int id : lightThemes)
    {
        if (m_themesId == id)
        {
            isLightTheme = true;
            break;
        }
    }
    
    // 暗色模式下不设置背景色，使用编辑器统一背景
    if (!isLightTheme)
    {
        return QsciLexer::defaultPaper(style);
    }
    
    // 亮色模式保留原有背景色
"""
    
    new_content = (
        content[:insert_pos] + 
        insert_code +
        content[insert_pos:]
    )
    
    # 移除所有 adjustColorForTheme 调用（只在 defaultPaper 中）
    # 这样亮色模式直接使用原始颜色
    new_content = re.sub(
        r'adjustColorForTheme\(QColor\(([^)]+)\)\)',
        r'QColor(\1)',
        new_content
    )
    
    with open(filepath, 'w', encoding='utf-8') as f:
        f.write(new_content)
    
    print(f"  ✓ 已修复 defaultPaper: {os.path.basename(filepath)}")
    return True

def main():
    print("开始批量修复暗色模式语法高亮...")
    print(f"目标目录: {QSCINT_DIR}\n")
    
    # 需要修复的文件（常用语言）
    target_files = [
        "qscilexerbash.cpp",
        "qscilexercpp.cpp",
        "qscilexercsharp.cpp",
        "qscilexercss.cpp",
        "qscilexerhtml.cpp",
        "qscilexerjava.cpp",
        "qscilexerjavascript.cpp",
        "qscilexerproperties.cpp",
        "qscilexersql.cpp",
        "qscilexerxml.cpp",
        "qscilexergo.cpp",
        "qscilexerrust.cpp",
        "qscilexeruby.cpp",
        "qscilexerperl.cpp",
        "qscilexerlua.cpp",
        "qscilexertcl.cpp",
    ]
    
    fixed_count = 0
    paper_fixed_count = 0
    
    for filename in target_files:
        filepath = os.path.join(QSCINT_DIR, filename)
        if not os.path.exists(filepath):
            print(f"  - 跳过（文件不存在）: {filename}")
            continue
        
        print(f"\n处理: {filename}")
        if add_dark_theme_to_defaultColor(filepath):
            fixed_count += 1
        
        if add_dark_theme_to_defaultPaper(filepath):
            paper_fixed_count += 1
    
    print(f"\n" + "="*60)
    print(f"修复完成！")
    print(f"  defaultColor 修复: {fixed_count} 个文件")
    print(f"  defaultPaper 修复: {paper_fixed_count} 个文件")
    print("="*60)
    print("\n请运行以下命令重新编译:")
    print(f"  cd {PROJECT_ROOT}/how_build/build")
    print("  make -j8")
    print("\n详细文档:")
    print(f"  {PROJECT_ROOT}/docs/maintenance/暗色模式修复完整总结.md")

if __name__ == "__main__":
    main()

